import time
import os
import requests
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

'''
    watchdog库的实现原理依赖于不同操作系统的底层文件系统事件通知机制，而不是低效的轮询（Polling）
    如果在linux系统内核：是一种事件驱动模型，效率极高，几乎不占用额外的 CPU 和磁盘 I/O 资源
    
'''

## 通过看门狗的方法把数据上传到数据中心
## ===================== 文件存储服务器配置 ===========================

from minio import Minio
from minio.error import S3Error
# 初始化 MinIO 客户端
minio_client = Minio(
    "8.137.58.206:9000",        # 替换为你的MinIO服务器地址
    access_key="9eBv4Rt6", # 替换为你的Access Key
    secret_key="3a7W5Mz8", # 替换为你的Secret Key
    secure=False             # 如果使用HTTPS(SSL/TLS)则为True，本地测试通常为False
)

class ImageUploadHandler(FileSystemEventHandler):
    def __init__(self, upload_url, api_key, watch_path):
        self.upload_url = upload_url
        self.headers = {'Authorization': f'Bearer {api_key}'}
        self.watch_path = watch_path
        self.retry_queue = []

    def on_created(self, event):
        if not event.is_directory and event.src_path.lower().endswith(('.jpg', '.png', '.jpeg')):
            print(f"检测到新文件: {event.src_path}")
            # 等待文件完全写入
            time.sleep(1)
            self.upload_file(event.src_path)

    def upload_file(self, file_path, max_retries=3):

        # # 图片本地路径和希望在MinIO中存储的对象名
        # local_file_path = "./test2.jpg"  # 替换为你的图片本地路径
        # bucket_name = "bucket1"  # 替换为你创建的存储桶名称
        # object_name = "test2.jpg"

        for attempt in range(max_retries):
            import time
            # 获取当前时间戳并转换为字符串
            timestamp = str(int(time.time()))
            object_name = timestamp + ".bmp"
            bucket_name = "bucket1"
            local_file_path = file_path
            try:
                # 调用 fput_object 上传图片
                minio_client.fput_object(
                    bucket_name,
                    object_name,
                    local_file_path,
                )
                print(f"图片 {local_file_path} 已成功上传为对象 {object_name}")
                print(f"上传成功: {file_path}")
                os.remove(file_path)  # 删除本地文件
                return True
            except S3Error as err:
                print(f"上传失败: {err}")

            except Exception as e:
                print(f"上传异常，尝试 {attempt + 1}/{max_retries}: {e}")
            # 最后一次尝试失败，保留文件
            if attempt == max_retries - 1:
                print(f"放弃上传，保留文件: {file_path}")
                return False
            time.sleep(2 ** attempt)  # 指数退避

        # """上传文件并处理重试逻辑"""
        # for attempt in range(max_retries):
        #     try:
        #         with open(file_path, 'rb') as f:
        #             files = {'image': f}
        #             response = requests.post(
        #                 self.upload_url,
        #                 files=files,
        #                 headers=self.headers,
        #                 timeout=30
        #             )
        #
        #         if response.status_code == 200:
        #             print(f"上传成功: {file_path}")
        #             os.remove(file_path)  # 删除本地文件
        #             return True
        #         else:
        #             print(f"上传失败，状态码: {response.status_code}")
        #
        #     except Exception as e:
        #         print(f"上传异常，尝试 {attempt + 1}/{max_retries}: {e}")
        #
        #     # 最后一次尝试失败，保留文件
        #     if attempt == max_retries - 1:
        #         print(f"放弃上传，保留文件: {file_path}")
        #         return False
        #
        #     time.sleep(2 ** attempt)  # 指数退避

    def start_monitoring(self):
        """开始监控"""
        observer = Observer()
        observer.schedule(self, self.watch_path, recursive=False)
        observer.start()
        print(f"开始监控目录: {self.watch_path}")
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            observer.stop()
        observer.join()


# 使用示例
if __name__ == "__main__":
    handler = ImageUploadHandler(
        upload_url="https://your-server.com/api/upload",
        api_key="your-api-key",
        watch_path="C:/Users/96523/Downloads/test"
    )
    handler.start_monitoring()

